package com.yesallchina.wxapp.officialaccount.api;

import com.yesallchina.wxapp.officialaccount.api.beans.param.ResponseDTO;
import com.yesallchina.wxapp.officialaccount.service.WxOfficialAccountInitializer;
import com.yesallchina.wxapp.officialaccount.utils.JacksonUtils;
import com.yesallchina.wxapp.officialaccount.utils.SHA1Encrypt;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;

/**
 * 微信公众号统一入口
 */
public class IndexApi extends WebController {

    private WxOfficialAccountInitializer wxInit;

    private MessageApi messageApi;

    private WebPageBaseSupportApi webPageBaseSupportApi;

    public IndexApi(MessageApi messageApi, WebPageBaseSupportApi webPageBaseSupportApi) {
        this.messageApi = messageApi;
        this.wxInit = messageApi.getWxInit();
        this.webPageBaseSupportApi = webPageBaseSupportApi;
    }

    private final static Logger log = LoggerFactory.getLogger(IndexApi.class);

    @RequestMapping("/wxofficialaccount/index")
    public void index(HttpServletRequest request, HttpServletResponse response) {
        response.setContentType("text/plain;charset=UTF-8");
        PrintWriter out = null;
        try {
            out = response.getWriter();
            String method = request.getMethod().toUpperCase();
            if ("GET".equals(method)) {
                out.print(ack(request));
                out.flush();
                return;
            }
            StringBuffer receivedData = new StringBuffer();
            InputStreamReader inReader = new InputStreamReader(request.getInputStream(), "UTF-8");
            BufferedReader mReader = new BufferedReader(inReader);
            String mLine = null;
            while ((mLine = mReader.readLine()) != null) {
                receivedData.append(mLine.trim());
            }
            String msgBody = receivedData.toString();
            if (log.isDebugEnabled()) {
                log.debug("[] : {}", msgBody);
            }
            // 将字符串转为XML
            if (msgBody.length() > 0) {
                // 处理XMl数据并得到回复的XML数据
                String resultBody = messageApi.receive(msgBody);
                out.print(resultBody);
                out.flush();
            }
        } catch (IOException e) {
            log.error("微信系统异常", e);
        } finally {
            if (out != null) {
                out.close();
            }
        }
    }

    @RequestMapping("/wxofficialaccount/jsapi/config")
    public void getJsApiConfig(HttpServletRequest request, HttpServletResponse response) {
        response.setContentType("application/json;charset=utf-8");
        PrintWriter out = null;
        try {
            out = response.getWriter();
            Object result = webPageBaseSupportApi.getJsSdkConfig(request.getParameter("url"));
            out.print(ResponseDTO.renderSuccess(result));
            out.flush();
        } catch (IOException e) {
            log.error("微信系统异常", e);
        } finally {
            if (out != null) {
                out.close();
            }
        }
    }


    private String ack(HttpServletRequest request) {
        // 第一次申请成为开发者
        String token = wxInit.getCommonProp().getMessageToken();
        // 微信加密签名
        String signature = request.getParameter("signature");
        if (StringUtils.hasText(signature)) {
            // 时间戳
            String timestamp = request.getParameter("timestamp");
            // 随机数
            String nonce = request.getParameter("nonce");
            // 随机字符串
            String echostr = request.getParameter("echostr");
            // 将token、timestamp、nonce三个参数进行字典序排序
            String[] strArray = new String[]{token, timestamp, nonce};
            java.util.Arrays.sort(strArray);
            String str = "";
            for (String s : strArray) {
                str += s;
            }
            String sign = SHA1Encrypt.SHA1(str);
            if (sign.equals(signature)) {
                if (StringUtils.hasText(echostr)) {
                    return echostr;
                }
            }
        }
        return "no info";
    }
}
